#include "config.h"
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <PubSubClient.h>


// OLED定义（128x64，I2C接口）
#define OLED_RESET -1

Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);

SoftwareSerial max485Serial(MAX485_RO, MAX485_DI);

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastSendTime = 0;


void setup() {
  Serial.begin(115200);
  Serial.println("\n[SETUP] 系统初始化...");
  // 初始化I2C引脚
  Wire.begin(SDA_PIN, SCL_PIN);  // 使用自定义SDA/SCL引脚
  // 初始化OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306初始化失败"));
    while(true);
  }
  // 初始化MAX485
  pinMode(MAX485_RE_DE, OUTPUT);
  setMax485ReceiveMode();
  max485Serial.begin(9600); 
  

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(F("System Starting..."));
  display.display();
  delay(1000);
  
  // 初始化WiFi
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println(F("Connecting to WiFi..."));
  display.display();
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println(".");
  }
  Serial.println("\nWiFi连接成功");
  
  // 初始化MQTT
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  lastSendTime = millis();
  reconnect();
}


void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
  }
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  
  // 定时发送指令到MAX485
  if (millis() - lastSendTime >= sendInterval) {
    String response = sendCommandAndWait(command, SERIAL_READ_TIMEOUT);
    
    if (response.length() > 140) {
      Serial.print("[MAX485] 接收数据: ");
      Serial.println(response);
      showLCD(response, 0, true);
      
      if (client.publish(mqtt_topic, response.c_str())) {
        Serial.println("[MQTT] 发布成功");
        showLCD("[MQTT] PUB OK", 1, true);
      } else {
        Serial.println("[MQTT] 发布失败");
        showLCD("[MQTT] PUB FAIL", 1, false);
      }
    } else {
      Serial.println("[MAX485] 接收超时");
      showLCD("[MAX485] TIMEOUT", 0, false);
    }
    
    lastSendTime = millis();
  }
}


// MAX485控制函数
void setMax485ReceiveMode() {
  digitalWrite(MAX485_RE_DE, LOW);
}

void setMax485TransmitMode() {
  digitalWrite(MAX485_RE_DE, HIGH);
  delay(1);
}

String sendCommandAndWait(const char* cmd, unsigned int timeoutMs) {
  setMax485TransmitMode();
  max485Serial.print(cmd);
  setMax485ReceiveMode();
  
  unsigned long startTime = millis();
  String response = "";
  
  while (millis() - startTime < timeoutMs) {
    if (max485Serial.available() > 0) {
      response += (char)max485Serial.read();
    }
  }
  
  return response;
}


// OLED显示函数（优化版）
void showLCD(String message, int lineIndex, bool mqttConnected) {
  display.clearDisplay();
  
  // 显示WiFi状态
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print(F("[WiFi] "));
  display.print(WiFi.localIP().toString());
  
  // 定义每行位置（10像素字体高度）
  const int lineYPos[] = {22, 34, 46};
  const int maxLines = 3;
  
  if (lineIndex < maxLines && message.length() > 0) {
    display.setCursor(0, lineYPos[lineIndex]);
    display.print(message);
  }
  
  // 显示时间和MQTT状态
  display.setCursor(0, 54);
  unsigned long currentTime = millis() / 1000;
  display.print(F("Time: "));
  display.print(currentTime);
  display.print(F("s  [MQTT] "));
  display.print(mqttConnected ? F("ON") : F("OFF"));
  
  display.display();
}


// MQTT回调函数
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(F("[MQTT] 收到消息, 主题: "));
  Serial.println(topic);
  
  String payloadStr;
  for (unsigned int i = 0; i < length; i++) {
    payloadStr += (char)payload[i];
  }
  Serial.println(payloadStr);
  
  showLCD(payloadStr, 0, true);
}


// 重连MQTT
void reconnect() {
  while (!client.connected()) {
    Serial.print(F("[MQTT] 尝试连接..."));
    showLCD(F("[MQTT] CONNECTING..."), 0, false);
    
    if (client.connect("ESP8266_BMS_Client")) {
      Serial.println(F("连接成功!"));
      showLCD(F("[MQTT] CONNECTED"), 0, true);
    } else {
      Serial.print(F("失败, 状态码: "));
      Serial.print(client.state());
      Serial.println(F(" 5秒后重试..."));
      showLCD(F("[MQTT] FAILED"), 0, false);
      showLCD(F("STATE: ") + String(client.state()), 1, false);
      delay(5000);
    }
  }
}